package br.ufmg.ubicomp.droidguide.application;

import java.util.Calendar;
import java.util.Collection;
import java.util.logging.Level;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.MenuItem;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import br.ufmg.ubicomp.droidguide.R;
import br.ufmg.ubicomp.droidguide.common.DroidGuideConfigurationManager;
import br.ufmg.ubicomp.droidguide.common.DroidGuideConstants;
import br.ufmg.ubicomp.droidguide.eventservice.UserEventBroadcastReceiver;
import br.ufmg.ubicomp.droidguide.eventservice.UserEventHandlingService;
import br.ufmg.ubicomp.droidguide.eventservice.UserEventProcessingService;
import br.ufmg.ubicomp.droidguide.eventservice.event.ServiceEvent;
import br.ufmg.ubicomp.droidguide.eventservice.notification.DGNotificationType;
import br.ufmg.ubicomp.droidguide.eventservice.notification.NotificationBucket;
import br.ufmg.ubicomp.droidguide.utils.AndroidUtils;
import br.ufmg.ubicomp.droidguide.utils.DateUtil;


public class Map extends Activity {

    private final int SEARCH_DIALOG = 0;
    protected String urlmap = "map/all?userid=";
    protected String userid = DroidGuideConfigurationManager.getInstance().getData(
                DroidGuideConstants.DROID_GUIDE_USER_KEY); 

    
    protected WebView wv;
    
    private static final byte USER_EVENT_SERVICE_METHOD = 0;
    // 0 = thread
    // 1 = broadcast receiver

    //private Handler mHandler = new Handler();

    @Override
    public void onCreate(Bundle icicle) {
        super.onCreate(icicle);
        setContentView(R.layout.map);
        
    	String url = DroidGuideConfigurationManager.getInstance().getData("server");
        
        wv = (WebView) findViewById(R.id.map);
        //wv.loadUrl("http://code.google.com/apis/maps/documentation/examples/geoxml-kml.html");
        
		//wv.loadUrl("http://droidguide.appspot.com/map/all?userid=agpkcm9pZGd1aWRlchULEg5Ecm9pZEd1aWRlVXNlchiZAww");
		
        wv.setWebViewClient(new MapWebViewClient());
        //wv.loadUrl("http://droidguide.appspot.com/map/all?userid=agpkcm9pZGd1aWRlchULEg5Ecm9pZEd1aWRlVXNlchjzCAw");
        wv.loadUrl(url+ urlmap + userid);
	
        WebSettings webSettings = wv.getSettings();
        webSettings.setJavaScriptEnabled(true);
        System.out.println("---------------------Starting services . . .");
        startServices();
    }
    
    private class MapWebViewClient extends WebViewClient {
    	@Override
    	public boolean shouldOverrideUrlLoading(WebView view, String url) {
    		if(url.indexOf("youtube") != -1 ){   			
    			Intent i;
        		i = new Intent( Map.this, MediaPlayer.class);
            	i.putExtra("videourl", url);
            	startActivity(i);
    		}	
    		else
    			view.loadUrl(url);
    		return true;
    	}
    	
    } 
    
    public boolean onCreateOptionsMenu(Menu menu) {
        super.onCreateOptionsMenu(menu);
        

//        menu.add(0,0, 0, "Profile").setIcon(R.drawable.profile)
//		 .setIntent(new Intent(android.provider.Settings.ACTION_SETTINGS));
//		 menu.add(0,1, 0, "How am I")
//		 .setIcon(R.drawable.android)
//		 .setIntent(new Intent(android.provider.Settings.ACTION_SETTINGS));
		 menu.add(0,2, 0, "Search")
		 .setIcon(R.drawable.find)
		 .setIntent(new Intent(android.provider.Settings.ACTION_SETTINGS));
		 menu.add(0,3, 0, "Route")
		 .setIcon(R.drawable.map)
		 .setIntent(new Intent(android.provider.Settings.ACTION_SETTINGS));
//		 menu.add(0,4, 0, "Info")
//		 .setIcon(R.drawable.info)
//		 .setIntent(new Intent(android.provider.Settings.ACTION_SETTINGS));
		 menu.add(0,5, 0, "Menu")
		 .setIcon(R.drawable.menu)
		 .setIntent(new Intent(android.provider.Settings.ACTION_SETTINGS));
		 
		// Add our submenu.
//		    SubMenu sub = menu.addSubMenu(1, 6, 1, "Days of the week");
//		    sub.add(1, 6, 0, "Monday");
//		    sub.add(1, 7, 1, "Tuesday");
//		    sub.add(1, 8, 2, "Wednesday");
//		    sub.add(1, 9, 3, "Thursday");
//		    sub.add(1, 10, 4, "Friday");
//		    sub.add(1, 11, 5, "Saturday");
//		    sub.add(1, 12, 6, "Sunday");
      return true;
    }
    
	@Override
    public boolean onOptionsItemSelected(MenuItem item){
		
    	Intent i = null;
    	//= new Intent("userEventService");
//    	sendBroadcast(i);
    	switch (item.getItemId()) {
        case 0: // profile
        	i = new Intent(this,Profile.class);
        	startActivity(i);
            return true;
            
        case 1: // how am i
        	AndroidUtils.startActivity(this, HowAmIActivity.class);
            return true;
        case 2: // search
        	showDialog(SEARCH_DIALOG);
            return true;
        case 3: // search
        	String url = DroidGuideConfigurationManager.getInstance().getData("server");
        	wv.loadUrl(url+"map/route?userid=agpkcm9pZGd1aWRlchULEg5Ecm9pZEd1aWRlVXNlchjeBAw");
            return true;
        case 4:
        	// start notification activity
        	AndroidUtils.startActivity(this, Info.class);
        	return true;
        case 5:
        	// logout
        	finish();
        	//executeLogout();
        	return true;
        }
        return false;
    }

	
    protected Dialog onCreateDialog(int id) {
        switch (id) {
        	case SEARCH_DIALOG:
                return new AlertDialog.Builder(this)
                .setTitle("Select a content to be show on the map:")
                .setItems(R.array.search_menu, new DialogClick())
                .create();
           
        }
		return new Dialog(this);
     }
    private class DialogClick implements DialogInterface.OnClickListener {
        public void onClick(DialogInterface dialog, int which) {
        	String url = DroidGuideConfigurationManager.getInstance().getData("server");

        	switch (which) {
            	case 0:
            		wv.loadUrl(url+"map/all?userid=agpkcm9pZGd1aWRlchULEg5Ecm9pZEd1aWRlVXNlchjeBAw&panoramio=true");
            		break;
            	case 1:
            		wv.loadUrl(url+"map/all?userid=agpkcm9pZGd1aWRlchULEg5Ecm9pZEd1aWRlVXNlchjeBAw&wikipedia=true");
        	}
        }
    }
    
	private void startServices() {
		
		Log.e(this.getClass().getSimpleName(), "starting services . . .");
		if (USER_EVENT_SERVICE_METHOD == 0)
		{
			startServicesUsingThread();
		} else
		{
			startServicesUsingBroadcast();
		}
	}

	private void startServicesUsingThread() {
		
		String updateInterval = DroidGuideConfigurationManager.getInstance().getData(DroidGuideConstants.UPDATE_INTERVAL);
		Log.d("UserEventService", "Interval = " + updateInterval + "000");
		
        Thread task = new Thread(){
        	
        	@Override
        	public void run() {
        		
        		int sent = sendEventsToServer();
        		
        		int received = readEventsFromServer(getApplicationContext());
        		
        		showEventNotification(sent, received);

        		long interval = Long.parseLong(DroidGuideConfigurationManager.getInstance().
        				getData(DroidGuideConstants.UPDATE_INTERVAL))*1000;
        		
        		AndroidUtils.runTask(this, interval);        		
        	}
        };
        
        AndroidUtils.runTask(task, 0);
	}

	private void showEventNotification(int sent, int received)
	{
		AndroidUtils.showNotification(this, "Events", 
				DateUtil.formatDate(Calendar.getInstance(), "hh:mm:ss") + " - Sent : " + sent + " | Received: " + received, 
				DGNotificationType.APPLICATION, "Events");
	}
	
	private int sendEventsToServer() {
		try {
			AndroidUtils.showAlert(this, "Updating events . . .");
			int i = UserEventHandlingService.getInstance().sendEventsToServer();
			checkConnectivity();
			
			return i;
		} catch (Exception e) {
			e.printStackTrace();
			AndroidUtils.notifyError(e, this, "SendEventsToServer");
		}
		return 0;
	}

	private void checkConnectivity() {
		String connectivityInfo = AndroidUtils.getConnectivityInfo(this);
		if (!connectivityInfo.equals(DroidGuideConfigurationManager.getInstance().getData("conn"))){
			DroidGuideConfigurationManager.getInstance().addData("conn", connectivityInfo);
			AndroidUtils.showNotification(this, "Conn", 
					connectivityInfo, DGNotificationType.OUTGOING, "Map");
		}
	}

	public int readEventsFromServer(Context context)
	{
		
		Collection<ServiceEvent> events = null;
		try {
			events = UserEventHandlingService.getInstance().readEventsFromServer();
		} catch (Exception e) {
			e.printStackTrace();
			AndroidUtils.notifyError(e, this, "readEventsFromServer");
		}				
		
		int received = events != null?events.size():0;
		handleIncommingEvents(events);
		return received;
	}
	
	private void handleIncommingEvents(Collection<ServiceEvent> events) {
		if (events != null)
		{
			for (ServiceEvent event: events)
			{
				NotificationBucket.getInstance().addNotification(DGNotificationType.INCOMMING, System.currentTimeMillis(), 
						event.getData(), "Server", Level.ALL);
				AndroidUtils.showNotification(this, "Service Event", event.getData(), DGNotificationType.INCOMMING, event.getType());
			}
		}
	}
	
    
	private void startServicesUsingBroadcast() {
		IntentFilter mFilter = new IntentFilter(DroidGuideConstants.USER_EVENT_BROADCAST_RECEIVER);
		UserEventBroadcastReceiver uebr = new UserEventBroadcastReceiver();
		registerReceiver(uebr, mFilter);		

		Handler h = new Handler();
		Thread task = new Thread(){
			@Override
			public void run() {
				
				Intent intent = new Intent(DroidGuideConstants.USER_EVENT_BROADCAST_RECEIVER);
				sendBroadcast(intent);		
				Handler h = new Handler();
				h.postDelayed(this, DroidGuideConstants.USER_EVENTS_UPDATE_INTERVAL);
			}
		};
		h.postDelayed(task, 0);
	}

	@Override
	protected void onDestroy() {
		super.onDestroy();

		// stop MyService
		{
			Intent userEventService = new Intent(this, UserEventProcessingService.class);
			stopService(userEventService);
		}
	}	
	
	@Override
	public boolean onKeyDown(int keyCode, KeyEvent event) {
		if (keyCode == KeyEvent.KEYCODE_BACK && event.getAction() == KeyEvent.ACTION_DOWN) {
				if (wv.canGoBack()) {
					wv.goBack();
					return true;
				}
			}
		return false;
	}
	
}
